/*
Miranda IM for Windows Search

Copyright (C) 2012-2014 Nikolay Raspopov

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "stdafx.h"
#include "MirandaSearch.h"
#include "MirandaAccessor.h"
#include "MirandaFilter.h"

// CMirandaAccessor

CMirandaAccessor::CMirandaAccessor()
	: m_nURLLevel	( URL_LEVEL_BAD )
{
}

HRESULT CMirandaAccessor::FinalConstruct()
{
	return S_OK;
}

void CMirandaAccessor::FinalRelease()
{
}

STDMETHODIMP CMirandaAccessor::Init(const CString& sURL)
{
	m_nURLLevel = ParseURL( sURL, m_sRelativeURL );
	if ( m_nURLLevel == URL_LEVEL_BAD )
	{
		ATLTRACE( "0x%08x : CMirandaAccessor : Init( \"%hs\" ) -> E_FAIL\n", GetCurrentThreadId(), (LPCSTR)CW2A( (LPCTSTR)sURL ) );
		return E_FAIL;
	}

	m_sURL = sURL;

	return S_OK;
}

// IUrlAccessor

STDMETHODIMP CMirandaAccessor::AddRequestParameter(PROPSPEC* /*pSpec*/, PROPVARIANT* /*pVar*/)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::AddRequestParameter() -> E_NOTIMPL\n", GetCurrentThreadId() );
#endif
	return E_NOTIMPL;
}

STDMETHODIMP CMirandaAccessor::GetDocFormat(__out_ecount_part(dwSize, *pdwLength) WCHAR /*wszDocFormat*/[], DWORD /*dwSize*/, __out DWORD* /*pdwLength*/)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::GetDocFormat() -> E_NOTIMPL\n", GetCurrentThreadId() );
#endif
	return E_NOTIMPL;
}

STDMETHODIMP CMirandaAccessor::GetCLSID(__out CLSID* pClsid)
{
	if ( ! pClsid )
		return E_POINTER;

	*pClsid = __uuidof( MirandaAccessor );

#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::GetCLSID() -> S_OK\n", GetCurrentThreadId() );
#endif
	return S_OK;
}

STDMETHODIMP CMirandaAccessor::GetHost(__out_ecount_part(dwSize, *pdwLength) WCHAR /*wszHost*/[], DWORD /*dwSize*/, __out DWORD* /*pdwLength*/)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::GetHost() -> E_NOTIMPL\n", GetCurrentThreadId() );
#endif
	return E_NOTIMPL;
}

STDMETHODIMP CMirandaAccessor::IsDirectory(void)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::IsDirectory() -> %s\n", GetCurrentThreadId(), ( m_nURLLevel == URL_LEVEL_CONTACTS || m_nURLLevel == URL_LEVEL_EVENTS ) ? "S_OK (yes)" : "S_FALSE (no)" );
#endif
	return ( m_nURLLevel == URL_LEVEL_CONTACTS || m_nURLLevel == URL_LEVEL_EVENTS ) ? S_OK : S_FALSE;
}

STDMETHODIMP CMirandaAccessor::GetSize(__out ULONGLONG *pllSize)
{
	if ( ! pllSize )
		return E_POINTER;

	*pllSize = 0;

#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::GetSize() -> E_NOTIMPL\n", GetCurrentThreadId() );
#endif
	return E_NOTIMPL;
}

STDMETHODIMP CMirandaAccessor::GetLastModified(__out FILETIME* /*pftLastModified*/)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::GetLastModified() -> E_NOTIMPL\n", GetCurrentThreadId() );
#endif
	return E_NOTIMPL;
}

STDMETHODIMP CMirandaAccessor::GetFileName(WCHAR /*wszFileName*/[], DWORD /*dwSize*/, DWORD* /*pdwLength*/)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::GetFileName() -> E_NOTIMPL\n", GetCurrentThreadId() );
#endif
	return E_NOTIMPL;
}

STDMETHODIMP CMirandaAccessor::GetSecurityDescriptor(__out_ecount_full(dwSize) BYTE* /*pSD*/, DWORD /*dwSize*/, __out DWORD* /*pdwLength*/)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::GetSecurityDescriptor() -> E_NOTIMPL\n", GetCurrentThreadId() );
#endif
	return E_NOTIMPL;
}

STDMETHODIMP CMirandaAccessor::GetRedirectedURL(WCHAR /*wszRedirectedURL*/[], DWORD /*dwSize*/, DWORD* /*pdwLength*/)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::GetRedirectedURL() -> E_NOTIMPL\n", GetCurrentThreadId() );
#endif
	return E_NOTIMPL;
}

STDMETHODIMP CMirandaAccessor::GetSecurityProvider(__out CLSID* /*pSPClsid*/)
{
	// default to NT security
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::GetSecurityProvider() -> S_FALSE\n", GetCurrentThreadId() );
#endif
	return S_FALSE;
}

STDMETHODIMP CMirandaAccessor::BindToStream(__deref_out IStream** /*ppStream*/)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::BindToStream() -> E_NOTIMPL\n", GetCurrentThreadId() );
#endif
	return E_NOTIMPL;
}

STDMETHODIMP CMirandaAccessor::BindToFilter(__deref_out IFilter **ppFilter)
{
	if ( ! ppFilter )
		return E_POINTER;

	*ppFilter = NULL;

	CComObject< CMirandaFilter >* pFilter;
	HRESULT hr = CComObject< CMirandaFilter >::CreateInstance( &pFilter );
	if ( SUCCEEDED( hr ) )
	{
		hr = pFilter->Init( m_sURL, m_sRelativeURL, m_nURLLevel );
		if ( SUCCEEDED( hr ) )
		{
			hr = pFilter->QueryInterface( ppFilter );
		}
		if ( FAILED( hr ) )
			pFilter->Release();
	}
		
#ifdef _DEBUG
	if ( FAILED( hr ) )
		ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::BindToFilter() -> 0x%08x\n", GetCurrentThreadId(), hr );
#ifdef _ATL_DEBUG_QI
	else
		ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor::BindToFilter() -> S_OK\n", GetCurrentThreadId() );
#endif
#endif

	return hr;
}

// IUrlAccessor2

STDMETHODIMP CMirandaAccessor::GetDisplayUrl(__out_ecount_part(dwSize, *pdwLength) WCHAR /*wszDocUrl*/[], DWORD /*dwSize*/, __out DWORD* /*pdwLength*/)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor2::GetDisplayUrl() -> E_NOTIMPL\n", GetCurrentThreadId() );
#endif
	return E_NOTIMPL;
}

STDMETHODIMP CMirandaAccessor::IsDocument(void)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor2::IsDocument() -> %s\n", GetCurrentThreadId(), ( m_nURLLevel == URL_LEVEL_MESSAGE ) ? "S_OK (yes)" : "S_FALSE (no)" );
#endif
	return ( m_nURLLevel == URL_LEVEL_MESSAGE ) ? S_OK : S_FALSE;
}

STDMETHODIMP CMirandaAccessor::GetCodePage(__out_ecount_part(dwSize, *pdwLength) WCHAR /*wszCodePage*/[], DWORD /*dwSize*/, __out DWORD* /*pdwLength*/)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor2::GetCodePage() -> E_NOTIMPL\n", GetCurrentThreadId() );
#endif
	return E_NOTIMPL;
}

// IUrlAccessor3

STDMETHODIMP CMirandaAccessor::GetImpersonationSidBlobs(__RPC__in LPCWSTR /*pcwszURL*/, __RPC__out DWORD * /*pcSidCount*/, __RPC__deref_out_opt BLOB ** /*ppSidBlobs*/)
{
#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor3::GetImpersonationSidBlobs() -> E_NOTIMPL\n", GetCurrentThreadId() );
#endif
	return E_NOTIMPL;
}

// IUrlAccessor4

STDMETHODIMP CMirandaAccessor::ShouldIndexItemContent(__RPC__out BOOL *pfIndexContent)
{
	if ( ! pfIndexContent )
		return E_POINTER;

	*pfIndexContent = TRUE;

#ifdef _ATL_DEBUG_QI
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor4::ShouldIndexItemContent() -> S_OK (yes)\n", GetCurrentThreadId() );
#endif
	return S_OK;
}

STDMETHODIMP CMirandaAccessor::ShouldIndexProperty(__RPC__in REFPROPERTYKEY key, __RPC__out BOOL *pfIndexProperty)
{
	key;

	if ( ! pfIndexProperty )
		return E_POINTER;

	*pfIndexProperty = TRUE;

#ifdef _ATL_DEBUG_QI
	LPOLESTR szGUID = NULL;
	StringFromCLSID( key.fmtid, &szGUID );
	ATLTRACE( "0x%08x : CMirandaAccessor : IUrlAccessor4::ShouldIndexProperty( %s.%u ) -> %s\n", GetCurrentThreadId(), (LPCSTR)CW2A( szGUID ), key.pid, ( *pfIndexProperty ? "Yes" : "No" ) );
	CoTaskMemFree( szGUID );
#endif

	return S_OK;
}

// IOpLockStatus
//
//STDMETHODIMP CMirandaAccessor::IsOplockValid(__out BOOL *pfIsOplockValid)  
//{
//	*pfIsOplockValid = TRUE;
//
//	ATLTRACE( "0x%08x : CMirandaAccessor : IOpLockStatus::IsOplockValid() -> %hs\n", GetCurrentThreadId(), ( *pfIsOplockValid ? "Yes" : "No" ) );
//
//	return S_OK;
//}
//
//STDMETHODIMP CMirandaAccessor::IsOplockBroken(__out BOOL *pfIsOplockBroken)
//{
//	*pfIsOplockBroken = FALSE;
//
//	ATLTRACE( "0x%08x : CMirandaAccessor : IOpLockStatus::IsOplockBroken() -> %hs\n", GetCurrentThreadId(), ( *pfIsOplockBroken ? "Yes" : "No" ) );
//
//	return S_OK;
//}
//
//STDMETHODIMP CMirandaAccessor::GetOplockEventHandle(__deref_out HANDLE *phOplockEv)
//{
//	*phOplockEv = NULL;
//
//	ATLTRACE( "0x%08x : CMirandaAccessor : IOpLockStatus::GetOplockEventHandle() -> 0x%08x\n", GetCurrentThreadId(), *phOplockEv );
//
//	return S_OK;
//}
